﻿using SaaS.Cache.Auths;
using SaaS.Model.Entity.Sites;
using SaaS.Model.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using XCore.Dependency;
using XCore.Extensions;
using XCore.Encryption;
using XCore.Web.Jwt;
using SaaS.Core;
using System.Security.Claims;

namespace Web.Admin.Services.Sites
{
    public class AdminAppService : AdminApplictionServiceBase, ISingletonDependency
    {
        private readonly AdminAuthCacheService _adminAuthCacheService;
        public AdminAppService(AdminAuthCacheService adminAuthCacheService)
        {
            _adminAuthCacheService = adminAuthCacheService;
        }
        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <returns></returns>
        public JWTResult Login(string username, string password)
        {
            if (username.IsNullOrWhiteSpace()) throw new AdminException("请输入用户名", AdminLoggerSource.Login);
            if (password.IsNullOrWhiteSpace()) throw new AdminException("请输入密码", AdminLoggerSource.Login);
            if (!(username.Length >= 4 && username.Length < 16)) throw new AdminException("用户名长度为4~16个字符", AdminLoggerSource.Login);
            if (!(password.Length >= 6 && password.Length < 32)) throw new AdminException("密码长度为6~32位字符", AdminLoggerSource.Login);
            SiteAdmin admin = ADC.SiteAdmins.Where(c => c.SiteId == Session.SiteId && c.UserName == username).FirstOrDefault();
            //检查用户名
            if (admin == null) throw new AdminException("用户名不存在", AdminLoggerSource.Login);
            //检查状态
            if (admin.Status == UserStatus.Disable || admin.Status == UserStatus.Locking) throw new AdminException($"账号已被:{admin.Status.GetDescription()}", AdminLoggerSource.Login);
            //检查密码
            if (!admin.Password.IsEqual(PwdEncryption.Encryption(password, admin.Id))) throw new AdminException("密码错误", AdminLoggerSource.Login);
            //生成token
            string token = JWTHelper.CreateToken(new JWTOptions(CoreSetting.Audience, CoreSetting.Issuer, CoreSetting.Expire),
                new[] {
                    new Claim("AdminId", admin.Id.ToString()),
                    new Claim("SiteId",admin.SiteId.ToString()),
                    new Claim("UserName",admin.UserName),
                    new Claim("IsDefault",admin.IsDefault.ToString()),
                    new Claim("RoleId",admin.RoleId.ToString()),
                    });
            //进入缓存
            _adminAuthCacheService.SetTenantToken(admin.Id, token);
            Logger.Log(admin.Id, $"[{admin.UserName}]--登录成功", AdminLoggerSource.Login);
            return new JWTResult(token, CoreSetting.Expire);
        }
        /// <summary>
        /// 创建及编辑
        /// </summary>
        /// <param name="id"></param>
        /// <param name="username"></param>
        /// <param name="roleId"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        public bool CreateOrEdit(int id, string username, int roleId, UserStatus status)
        {
            SiteAdmin admin = new SiteAdmin
            {
                Id = id,
                RoleId = roleId,
                Password = PwdEncryption.Encryption(CoreSetting.DefaultPassword, Session.SiteId),
                InitPassword = CoreSetting.DefaultPassword,
                Status = status,
                SiteId = Session.SiteId,
                UserName = username
            };
            if (!(admin.UserName.Length >= 4 && admin.UserName.Length < 16)) throw new AdminException("用户名长度为4~16个字符", AdminLoggerSource.Login);
            if (ADC.SiteAdmins.Any(c => c.SiteId == admin.SiteId && c.Id != c.Id && c.UserName == admin.UserName)) throw new AdminException("已存在相同用户名", AdminLoggerSource.Admin);
            if (admin.Id == 0)
            {
                return Repository.Insert(admin) && Logger.Log("添加管理员", AdminLoggerSource.Admin);
            }
            else
            {
                return Repository.Update(admin, c => c.Id == id, c => c.UserName, c => c.RoleId, c => c.Status) && Logger.Log("修改管理员信息", AdminLoggerSource.Admin);
            }
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool Delete(int id)
        {
            if (ADC.SiteAdmins.Any(c => c.Id == id && c.SiteId == Session.SiteId && c.IsDefault)) throw new AdminException("默认超级管理员不可删除", AdminLoggerSource.Admin);
            return Repository.Delete<SiteAdmin>(id) && Logger.Log("删除管理员", AdminLoggerSource.Admin);
        }
    }
}
